package dS.ProjectGPS.NTrip;

import dS.ProjectGPS.*;
import dS.ProjectGPS.Bluetooth.*;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;

/**
 * <p>Title: NTripClient</p>
 *
 * <p>Description: Connects to specified NTRIPCaster service via GPRS
 *                 and streams selected Mountpoint to given Bluetooth
 *                 connection. (Output to any StreamConnection)</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * @author David So
 * @version 1.0
 */


public class NTripClient extends Thread implements CommandListener {


  private static final String AGENT_STRING = "NTRIP ProjectGPSse/0.1";

//  public static String HOST_NAME = "129.94.167.180";
  public static String HOST_NAME = "www.euref-ip.net";
  public static int HTTP_PORT = 2101;

  public static String MOUNT_POINT = "SYDN0";
  public static String USER_NAME = "user96";
  public static String USER_PASS = "hfjfkp";
  String encryptedAccess = "dXNlcjk2OmhmamZrcA==";


  public static final Command CMD_NTRIPC_START = new Command("Start",
     Command.ITEM, 1);
  public static final Command CMD_NTRIPC_STOP = new Command("Stop",
     Command.ITEM, 2);
  public static final Command CMD_NTRIPC_RESET = new Command("Reset",
     Command.ITEM, 3);
  public static final Command CMD_BACK = new Command("Back", Command.BACK, 1);
  public static final Command CMD_SAVE = new Command("Save", Command.ITEM, 3);


  public List menu;
  private String[] menuNames = {"Server Settings", "Select Mountpoint","Stream!"};

  List mountpoints = new List("Mountpoints", List.EXCLUSIVE);

  FormNTripClient ncServer = new FormNTripClient();

  Display display = null;

  // Connection to Internet NTrip Server
  StreamConnection c = null;
  PrintStream outToServer;
  InputStream inFromServer;

  // Connection to Serial or Bluetooth Output PrintStream
  public boolean serialOut = false;
  public PrintStream serialOutStream = null;

  // Displays the incoming data on screen
  MessageUI gnssScreen = new MessageUI();


  public NTripClient(Display d) {

    display = d;

    menu = new List("NTripClient", Choice.IMPLICIT, menuNames, null);

    menu.setCommandListener(this);
    menu.addCommand(CMD_BACK);

    ncServer.addCommand(CMD_BACK);
    ncServer.addCommand(CMD_SAVE);

    mountpoints.setCommandListener(this);
    mountpoints.addCommand(CMD_BACK);
    mountpoints.addCommand(CMD_SAVE);

    gnssScreen.addCommand(CMD_NTRIPC_STOP);
    gnssScreen.addCommand(CMD_NTRIPC_START);
  }

  public void getSourceTable() {

    try {

      c = (StreamConnection) Connector.open("socket://" + HOST_NAME + ':' +
                                            HTTP_PORT);

      System.out.println("Connected");

      outToServer = new PrintStream(c.openOutputStream());
      outToServer.print("GET / HTTP/1.0\r\n");
      //outToServer.print("User-Agent: " + AGENT_STRING + "\r\n");
      outToServer.print("User-Agent: NTRIP NtripLinuxClient/1.9\r\n");
      outToServer.print("Authorization: Basic " + encryptedAccess + "\r\n\n\n");
      outToServer.print("\r\n\n\n");
      outToServer.flush();

      System.out.println("Sent GET command");

      inFromServer = c.openInputStream();


      System.out.println("inFromServer connection");

      int ch;
      int index = 0;
      int i = 0;
      String sentence = new String();

     /*  while ((ch = isr.read()) != -1) {
        System.out.print((char) ch);
       sentence += (char) ch;
        if (ch == '\n') {
          System.out.println(sentence);

          sentence = "";
        }
      }*/


      while (!sentence.startsWith("ENDSOURCETABLE")) {
        ch = inFromServer.read();
        sentence += (char) ch;
        if (ch == '\n') {
          if(sentence.startsWith("STR")){
            String[] sa = StringTokenizer.tokenizeString(sentence, ";");
            if (sa.length > 0) {
              i++;
              System.out.println(i + " " + sa[1]);
              mountpoints.append(sa[1], null);
              //gnssScreen.add(sa[1]);
              if(sa[1] == MOUNT_POINT){
                mountpoints.setSelectedIndex(index, true);
              }
            }
          }
          index++;
          sentence = "";
        }
      }
    }
    catch (IOException ioe) {
      System.out.println("\nIgnore IOException");
    }
    catch (Exception e) {
      System.out.println("Could not get source table");
      System.out.println(e.getMessage());
      gnssScreen.add(e.getMessage());
      e.printStackTrace();
    }

    finally {
      stop();
    }

    return;
  }


  public void run() {

    try {

      c = (StreamConnection) Connector.open("socket://" + HOST_NAME + ':' +
                                            HTTP_PORT);

      System.out.println("Connected");

      outToServer = new PrintStream(c.openOutputStream());
      outToServer.print("GET /" + MOUNT_POINT + " HTTP/1.0\r\n");
      outToServer.print("User-Agent: " + AGENT_STRING + "\r\n");
      outToServer.print("Authorization: Basic " + encryptedAccess + "\r\n\n\n");
      outToServer.flush();

      System.out.println("Sent GET command");

      inFromServer = c.openInputStream();

      System.out.println("inFromServer connection");


      int ch;
      String sentence = new String();

      while ((ch = inFromServer.read()) != -1) {
        System.out.print((char) ch);
        sentence += (char) ch;
        if (ch == '\n') {
          gnssScreen.add(sentence);

          if(serialOut){
            serialOutStream.println(sentence);
            serialOutStream.flush();
          }

          sentence = "";
        }
      }
    }

    catch (Exception e) {
      System.out.println("Cant open the socket connection");
      System.out.println(e.getMessage());
      e.printStackTrace();
    }

    finally {
      stop();
    }

    return ;
  }

  public void stop() {
    try {
      if (inFromServer != null) {
        inFromServer.close();
      }

      if (c != null) {
        c.close();
      }
    }
    catch (Exception e) {
      // Ignore
    }
  }


  public void commandAction(Command c, Displayable d) {
    if (d.equals(menu)) {
      if (c == CMD_BACK) {
        display.setCurrent(ProjectGPSme.mainMenu);
      } else {
        //Retrieving the selected index from the list
        switch (((List) d).getSelectedIndex()) {
          case 0: { // Server Settings
            ncServer.update();
            display.setCurrent(ncServer);
            ncServer.setCommandListener(this);
            break;
          }
          case 1: { // Sourcetable
            display.setCurrent(mountpoints);
            getSourceTable();
            break;
          }
          case 2: { // Stream
            gnssScreen.setCommandListener(this);
            display.setCurrent(gnssScreen);
            break;
          }
        }
      }
    } else if (c == CMD_NTRIPC_START) {
      gnssScreen.removeCommand(CMD_NTRIPC_START);
      gnssScreen.addCommand(CMD_NTRIPC_RESET);
      start();
    }
    else if (c == CMD_NTRIPC_STOP) {
      stop();
    }
    else if (c == CMD_NTRIPC_RESET) {
      // Goes back to main menu so new NTripClient thread can be created
      Alert alert = new Alert("Reset", "You will be taken back to main menu.", null,
                        AlertType.CONFIRMATION);
      alert.setTimeout(3000);
      display.setCurrent(alert, ProjectGPSme.mainMenu);

    }
    else if (c == CMD_SAVE) {
      if(d.equals(ncServer)){
        ncServer.save();

      } else { // mountpoints list
        int i = mountpoints.getSelectedIndex();
        MOUNT_POINT = mountpoints.getString(i);
      }
      display.setCurrent(menu);
    }
    else if (c.getLabel().equals("Back")) {
      display.setCurrent(menu);
    }
  }
}
